package com.xpxrule.strategy.operator;

import com.xpxrule.constant.FieldType;
import com.xpxrule.constant.ValueType;
import com.xpxrule.dataobject.base.Range;
import com.xpxrule.dataobject.bo.RuleConditionItemBo;
import com.xpxrule.exception.OperatorUseIllegalException;
import com.xpxrule.strategy.FieldTypeStrategyContext;
import com.xpxrule.strategy.field.FieldTypeStrategy;

import java.util.List;
import java.util.Map;

/**
 * @version 1.0
 * @Author xiangpengxiang
 * @Date 2025/1/2 19:31
 * @注释
 */
public abstract class OperatorStrategy {
    public String getAviatorExpression(RuleConditionItemBo conditionItemBo, Map<String, Object> params) throws OperatorUseIllegalException {
        String aviatorExpression = null;
        // 获取目标值取值类型
        ValueType valueType = conditionItemBo.getTargetValue().getValueType();
        boolean operatorUseVerify = operatorUseVerify(valueType);
        if (!operatorUseVerify) {
            /**
             * todo xpx 抛出异常，操作符使用不合法
             * 如equal不能进行rang、list操作，仅能使用single操作
             */
            throw new OperatorUseIllegalException();
        }
        // 获取字段类型策略
        FieldType fieldType = FieldType.getValueTypeByType(conditionItemBo.getFieldBasicType().getType());
        FieldTypeStrategy fieldTypeStrategy = FieldTypeStrategyContext.getFieldTypeStrategy(fieldType);
        String fieldKey = conditionItemBo.getFieldKey();
        // 根据取值类型执行对应方法
        switch (valueType) {
            case SINGLE:
                Object singleValue = conditionItemBo.getTargetValue().getSingle();
                Object singleLeftValue = getSingLeftValue(fieldTypeStrategy, params, fieldKey);
                Object singleRightValue = getSingleRightValue(fieldTypeStrategy, singleValue);
                aviatorExpression = getAviatorExpressionBySingleValue(fieldKey, singleLeftValue, singleRightValue, fieldType);
                break;
            case RANGE:
                Range rangeValue = getRangeRightValue(fieldTypeStrategy, conditionItemBo.getTargetValue().getRange());
                Object rangeLeftValue = getRangeLeftValue(fieldTypeStrategy, params, fieldKey);
                aviatorExpression = getAviatorExpressionByRangeValue(fieldKey, rangeValue, conditionItemBo, params, fieldTypeStrategy, fieldType);
                break;
            case COLLECTION:
                List collectionRightValue = getCollectionRightValue(fieldTypeStrategy, conditionItemBo.getTargetValue().getList());
                Object collectionLeftValue = getCollectionLeftValue(fieldTypeStrategy, params, fieldKey);
                aviatorExpression = getAviatorExpressionByCollectionValue(fieldKey, collectionRightValue, conditionItemBo, params, fieldTypeStrategy, fieldType);
                break;
            default:
                break;
        }
        return aviatorExpression;
    }

    protected boolean operatorUseVerify(ValueType valueType) {
        boolean useVerify = true;
        switch (valueType) {
            case SINGLE:
                useVerify = true;
                break;
            case RANGE:
                useVerify = true;
                break;
            case COLLECTION:
                useVerify = true;
                break;
        }
        return useVerify;
    }

    protected Object getSingLeftValue(FieldTypeStrategy fieldTypeStrategy, Map<String, Object> params, String fieldKey) {
        return fieldTypeStrategy.getFieldObject(params.get(fieldKey));
    }

    protected Object getSingleRightValue(FieldTypeStrategy fieldTypeStrategy,Object singleValue) {
        return fieldTypeStrategy.getFieldObject(singleValue);
    }

    protected Object getRangeLeftValue(FieldTypeStrategy fieldTypeStrategy, Map<String, Object> params, String fieldKey) {
        return fieldTypeStrategy.getFieldObject(params.get(fieldKey));
    }

    protected Range getRangeRightValue(FieldTypeStrategy fieldTypeStrategy,Range rangeValue) {
        return fieldTypeStrategy.getFieldRange(rangeValue);
    }

    protected Object getCollectionLeftValue(FieldTypeStrategy fieldTypeStrategy, Map<String, Object> params, String fieldKey) {
        return fieldTypeStrategy.getFieldObject(params.get(fieldKey));
    }

    protected List getCollectionRightValue(FieldTypeStrategy fieldTypeStrategy, List<Object> listValue) {
        return fieldTypeStrategy.getFieldCollection(listValue);
    }

    abstract String getAviatorExpressionByCollectionValue(String fieldKey, List<Object> listValue, RuleConditionItemBo conditionItemBo, Map<String, Object> params, FieldTypeStrategy fieldTypeStrategy, FieldType fieldType);

    abstract String getAviatorExpressionByRangeValue(String fieldKey, Range<Object> rangeValue, RuleConditionItemBo conditionItemBo, Map<String, Object> params, FieldTypeStrategy fieldTypeStrategy, FieldType fieldType);

    abstract String getAviatorExpressionBySingleValue(String fieldKey, Object left, Object right, FieldType fieldType);
}
